
#pragma once

#include "ECommon.h"
#include <Windows.h>

/*
 * 图形渲染底层分两种实现, 一种为GDI一种为GDI+, 当需要使用GDI+时取消下面的注释重新编译即可
 * 但是GDI+的效率差GDI很多, 虽然他们使用的方法相同
 * #define GRAPHICS_DGIPLAS 1
 */

#ifdef GRAPHICS_DGIPLAS
#include <GdiPlus.h>
#endif

namespace Eyas3D
{
	/*
	 * 用于底层绘制图像, 实现像素级别的绘制功能, 底层实现使用GDI+
	 * 调用方法
	 * // 初始化GDI+
	 * InitDraw()
	 * HDC          hdc;
	 * PAINTSTRUCT  ps;
	 * // 循环绘制
	 * while(1)
	 * {
	 * // 获得hdc
	 * hdc = BeginPaint(hWnd, &ps);
	 * // 清楚缓冲区
	 * ClearBuffer()
	 * // 绘制操作
	 * ....
	 * DrawLine(...)
	 * ....
	 * // 翻转缓冲区
	 * FillBuffer(hdc)
	 *
	 * //释放hdc
	 * EndPaint(hWnd, &ps);
	 * }
	 * // 结束 释放GDI+
	 * ShutdownDraw()
	 */
	extern HINSTANCE GHInstance;
	/*
	 * 图片封装, 由于图片使用的GDI+的图片类,
	 * 所以这里对他进行封装, 将平台相关的东西隐藏
	 */
	class EBitmap
	{
	public:
		EInt width, height;
		EBitmap( const EString &filename );
		~EBitmap();
		inline EString getName() const
		{
			return(name);
		}
		inline bool isValid() const
		{
			return(valid);
		}
		EColor getPixel( EInt x, EInt y );
		inline EInt getHeight() const
		{
			return(height);
		}
		inline EInt getWidth() const
		{
			return(width);
		}
	private:
		EString name;
//sdl
		SDL_Surface* surface;
		
#ifdef GRAPHICS_DGIPLAS
		Gdiplus::Bitmap		*bitmap;
		Gdiplus::BitmapData	*bitmapData;
	public:
		UINT *pixels;
#else
		HBITMAP hBitmap;
		BITMAP	bitmap;
		HDC	bitmapHDC;
	public:
		EColor *pixels;
#endif
		EInt	pitch;
		EBool	valid;
	};
	
	class EGraphics
	{
	public:
		/* 初始化绘图系统 */
		static bool initGraphics( HINSTANCE hinstance );
		/* 关闭绘图系统 */
		static void shutdownGraphics();
		/* 检测z值, 返回true则表示通过, 可以调用setPixel */
		static EBool checkZ( EInt x, EInt y, EFloat z );
		static void setPixel( EInt x, EInt y, /*EFloat z, */ const EColor &c );
		static EColor getPixel( EInt x, EInt y );
		/* 在当前缓冲区内绘制一条线 */
		static void drawLine( EInt x0, EInt y0, EInt x1, EInt y1, const EColor &c );
		static void drawString( const EString &str, EInt x, EInt y, const EColor &c = EColor( 255, 255, 255 ) );
		static void fillTriangle( EInt x0, EInt y0, EInt x1, EInt y1, EInt x2, EInt y2,
					  const EColor &c = EColor( 255, 255, 255 ) );
		static void enableSmoothingMode( EBool enable );
		/* 清空当前缓冲区, 并将其颜色设置为黑色 */
		static void clearBuffer( const EColor &c = EColor() );
		/* 将已经绘制好的缓冲区递交给Graphics在屏幕上绘制, 并将当前缓冲区设置为另一个缓冲区 */
		static void fillBuffer( HDC hdc );
		static EInt getScreenWidth()
		{
			return(SCREEN_WIDTH);
		}
		static EInt getScreenHeight()
		{
			return(SCREEN_HEIGHT);
		}
	private:
#ifdef GRAPHICS_DGIPLAS
		static Gdiplus::GdiplusStartupInput GDiplusStartupInput;
		static ULONG_PTR GDiplusToken;
		/* 主缓冲区和后缓冲区 */
		static Gdiplus::Bitmap		*GCurrentBuffer;
		static Gdiplus::Graphics	*GCurrentGraphics;
		static Gdiplus::Font *GFont;
		static Gdiplus::BitmapData	*GBitmapData;
		static UINT			*GPixels;
#else
		/* 保存变量 */
		static HBITMAP GBufferedHandle;
		static HDC		GBufferedHDC;
		static HBRUSH		GBgBrush;
		static HPEN		GPen;
		static HINSTANCE	GInstance;
		static BYTE	*GDatas;
		static EInt	GPitch;
		static DIBSECTION GDIBSection;
		static RECT GBufferSize;
#endif
		static EFloat *GZBuffer;
	};
}
